#include "SpaceShip.h"


SpaceShip::SpaceShip(void)
{
}


SpaceShip::~SpaceShip(void)
{
}

void SpaceShip::Initialize(CL_GraphicContext& gc, vector<CL_Vec3f> positions, vector<CL_Vec3f> points)
{
	m_position = positions[0];
	m_position.y -=25;
	m_position.x += 5;
	
	m_startPosition.y = positions[0].y + 10;
	m_startPosition.x = positions[0].x;
	m_endPosition.y = positions[1].y + 10;
	m_endPosition.x = positions[1].x;

	m_points = points;
	
	m_velocity = CL_Vec3f(0.0f, 0.0f, 0.0f);
	m_speed = CL_Vec3f(0.0f, 0.0f, 0.0f);

	m_fuel = 200;
}

void SpaceShip::Draw(CL_GraphicContext& gc)
{
	CL_Pointf pos;
	pos.x = m_position.x;
	pos.y = m_position.y;
	CL_Draw::fill(gc,CL_Rectf(pos, CL_Sizef(SPACESHIP_SIZE,SPACESHIP_SIZE)),CL_Colorf::aqua);
	CL_Draw::fill(gc,CL_Rectf(CL_Pointf(10,10),CL_Sizef(m_fuel, 20)),CL_Colorf::red);
}

void SpaceShip::Update(float dt)
{
	bool collision = false;
	bool safeCollisionStart = false, safeCollisionEnd = false;
	CL_Console::write_line("%1 - %2 - %3",m_velocity.x, m_velocity.y, m_velocity.z);
	for(int i = 0; i < m_points.size()-1; i++)
	{
		if(CheckCollisions(m_points[i], m_points[i+1], m_position, SPACESHIP_SIZE))
		{
			collision = true;

			//collision, but on savepoints
			if(m_points[i].x == m_startPosition.x)
			{
				safeCollisionStart = true;
			}
			if(m_points[i].x == m_endPosition.x)
			{
				safeCollisionEnd = true;
			}
		}
	}
	
	if(collision)
	{
		if(safeCollisionStart)
		{
			//CL_Console::write_line("safe collision");
			m_velocity = m_velocity + m_speed*dt/2;
			m_position = m_position + m_velocity*dt;
			m_velocity = m_velocity + m_speed*dt/2;
			m_velocity.x = 0;
			if(m_position.y +10 > m_startPosition.y)
			{
				m_position.y = m_startPosition.y -10;
			}
		}
		else if (safeCollisionEnd)
		{
			//CL_Console::write_line("safe collision");
			m_velocity = m_velocity + m_speed*dt/2;
			m_position = m_position + m_velocity*dt;
			m_velocity = m_velocity + m_speed*dt/2;
			m_velocity.x = 0;
			if(m_position.y +10 > m_endPosition.y)
			{
				m_position.y = m_endPosition.y -10;
			}
		}
		else
		{
			CL_Console::write_line("collision!!!!!!!!!!!!");
			m_position = m_position;
		}
		
	}
	else
	{
			m_velocity = m_velocity + CL_Vec3f(0.0f,GRAVITY,0.0f)*dt/2 + m_speed*dt;
			m_position = m_position + m_velocity*dt;
			m_velocity = m_velocity + CL_Vec3f(0.0f,GRAVITY,0.0f)*dt/2 + m_speed*dt;
	}
	
}



bool SpaceShip::CheckCollisions(CL_Vec3f start, CL_Vec3f end, CL_Vec3f position, int size)
{
	CL_Pointf TL = position;
	CL_Pointf TR = CL_Pointf(position.x + size, position.y);
	CL_Pointf BL = CL_Pointf(position.x, position.y + size);
	CL_Pointf BR = CL_Pointf(position.x + size, position.y + size);
	
	//check if corners are above, below or on the line segment
	//checkvalue > 0 : above
	//checkvalue < 0: below
	//checkvalue == 0: on
	int checkTL = (end.y - start.y) * TL.x + (start.x-end.x) * TL.y + (end.x * start.y - start.x * end.y);
	int checkTR = (end.y - start.y) * TR.x + (start.x-end.x) * TR.y + (end.x * start.y - start.x * end.y);
	int checkBL = (end.y - start.y) * BL.x + (start.x-end.x) * BL.y + (end.x * start.y - start.x * end.y);
	int checkBR = (end.y - start.y) * BR.x + (start.x-end.x) * BR.y + (end.x * start.y - start.x * end.y);

	//if all corner points are above or below line segment -> no intersection
	if(checkTL < 0 && checkTR < 0 && checkBL < 0 && checkBR < 0 
		|| checkTL > 0 && checkTR > 0 && checkBL > 0 && checkBR > 0)
	{
		return false;
	}
	else
	{
		//line to right of rect
		if(start.x > TR.x && end.x > TR.x)
			return false;
		//line to left of rect
		if(start.x < BL.x && end.x < BL.x)
			return false;

		if(start.y != end.y)
		{
			//line above rect
			if(start.y > TR.y && end.y > TR.y)
				return false;
			//line below rect
			if(start.y < BL.y && end.y < BL.y)
				return false;
		}
		//line is even (y values are equal)
		else
		{
			//line below rect
			if(TR.y > start.y && BL.y > start.y)
				return false;			
		}

		return true;
	}

}